package com.mikgonz.farkle;

import java.util.ArrayList;
import java.util.HashMap;

public class GameController {

	private ArrayList<String> players = new ArrayList<String>();
	private HashMap<String, Integer> playerScores = new HashMap<String, Integer>();
	private int round = 0;
	private DieManager dM;

	private GameScreen UI;

	private String currPlayer;
	private Scorer mScorer;

	private int scoreToBe = 0;
	private boolean isRoundEnded = true;

	public GameController(int numOfPlayers, GameScreen ui) {

		// TODO implement ai players using sharedpreferences
		for (int i = 1; i <= numOfPlayers; i++) {
			String playerName = "Player" + i;
			players.add(playerName);
			playerScores.put(playerName, 0);

		}

		dM = new DieManager();
		UI = ui;
		mScorer = new Scorer();
		updateUIScore();

		startRound();
	}

	public void startRound() {

		isRoundEnded = false;

		currPlayer = players.get(round % players.size());

		// TODO Check to see if @currPlayer is AI

		scoreToBe = 0;
	}

	public void endRound(boolean isFarkle) {

		String message = "";

		message = (isFarkle) ? (currPlayer + " has Farkled")
				: (currPlayer + " has Scored");

		UI.displayMessage(message);

		UI.rollButtonState(true);
		UI.scoreButtonState(false);

		UI.updateImages(false, isFarkle);
		if (!isFarkle)
			dM.clearTable();
		updateUIScore();

		round++;
		isRoundEnded = true;
	}

	private void updateUIScore() {
		String message = "";
		String currPlayer = "";

		for (int i = 0; i < players.size(); i++) {
			currPlayer = players.get(i);
			message += currPlayer + "'s Score: " + playerScores.get(currPlayer)
					+ "\n";
		}

		UI.updateScoreBox(message);

	}

	public void onRoll() {
		if (isRoundEnded)
			startRound();

		UI.rollButtonState(false);
		UI.scoreButtonState(false);

		// If there are no dice highlighted then its the first roll of the round
		if (dM.getHighlighted(DieManager.INDEX_FLAG) != null) {

			int[] highlighted = dM.getHighlighted(DieManager.ABS_VALUE_FLAG);
			int scoreOnTable = mScorer.calculate(highlighted);

			scoreToBe += scoreOnTable;
			int possibleScore = scoreToBe + playerScores.get(currPlayer);
			UI.displayMessage("Picked up " + scoreToBe + ". " + currPlayer
					+ "'s new score could be " + possibleScore);

			dM.pickUp(dM.getHighlighted(DieManager.INDEX_FLAG));

		}

		dM.rollDice();
		UI.updateImages(true, false);

		int score = mScorer.calculate(dM.diceOnTable(DieManager.VALUE_FLAG));
		if (score == 0)
			endRound(true);
		else
			UI.updateImages(true, false);
	}

	public void onClickDice(int index) {

		if (!isRoundEnded) {

			int value = dM.getValue(index, DieManager.ABS_VALUE_FLAG);

			boolean isValid = false;

			int[] pairs = dM.findPairs(index, DieManager.INDEX_FLAG);
			if (pairs != null) {

				int[] valuesOfPairs = new int[pairs.length + 1];
				for (int i = 0; i < valuesOfPairs.length; i++)
					valuesOfPairs[i] = value;

				isValid = (mScorer.calculate(valuesOfPairs) != 0)
						|| (mScorer.isThreePair(dM
								.diceOnTable(DieManager.ABS_VALUE_FLAG)));

			}

			// Highlight if 5 or 1 else check to see if the are enough dice to
			// highlight
			if (value == 5 || value == 1) {

				dM.toggleHighlight(index);

			} else if (!isValid) {

				UI.displayMessage("Invalid Move. Not enough "
						+ dM.getValue(index, DieManager.ABS_VALUE_FLAG) + "'s");

			} else {

				for (int i = 0; i < pairs.length; i++)
					dM.toggleHighlight(pairs[i]);
				dM.toggleHighlight(index);
			}

			if (dM.getHighlighted(DieManager.INDEX_FLAG) != null
					&& mScorer.calculate(dM
							.getHighlighted(DieManager.ABS_VALUE_FLAG)) != 0) {
				UI.rollButtonState(true);
				UI.scoreButtonState(true);
			} else {
				UI.rollButtonState(false);
				UI.scoreButtonState(false);
			}

			UI.updateImages(false, false);
		}
	}

	// Will add the score and commence the new Round
	public void onScore() {

		int[] highlighted = dM.getHighlighted(DieManager.ABS_VALUE_FLAG);

		int onTable = mScorer.calculate(highlighted);
		int newScore = playerScores.get(currPlayer) + onTable + scoreToBe;
		playerScores.put(currPlayer, newScore);

		UI.displayMessage(currPlayer + "'s New Score is: " + newScore);
		endRound(false);
	}

	public int getImage(int index) {
		return dM.getImage(index);
	}

	public void newUI(GameScreen newUI) {
		UI = newUI;
	}

	public boolean shouldAnimate(int index) {
		return (dM.getValue(index, DieManager.VALUE_FLAG) > 0);
	}

	public void clearTable() {
		dM.clearTable();

	}

}
